/*
 * Copyright (C) 2003, Velocityme Partnership
 * TimeBean.java
 *
 * Created on 10 June 2003, 09:23
 */

package com.velocityme.entity;

import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import java.util.*;
import com.velocityme.interfaces.*;
import com.velocityme.valueobjects.TimeValue;
import com.velocityme.interfaces.ServiceUnavailableException;

/**
 *
 * @author  Robert Crida Work
 * @ejb.bean
 *           type="CMP"
 *           cmp-version="2.x"
 *           name="Time"
 *           jndi-name="ejb/Time"
 *           view-type="local"
 * @ejb.transaction type="Required"
 *
 * @ejb.value-object match="*"
 *
 * @ejb.persistence table-name="time"
 *
 * @ejb.util generate="physical"
 *
 * @ejb.finder signature="java.util.Collection findMyTime(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.PersonLocal p_person, java.util.Date p_start, java.util.Date p_stop)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) n, Time t WHERE t.personLocal = ?2 AND s = ?1 AND n.type = 'Task' AND t.taskLocal = n.taskLocal AND t.startTime > ?3 AND t.startTime < ?4" 
 *
 * @ejb.finder signature="java.util.Collection findTimeForPersons(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.SearchLocal p_personSearch, java.util.Date p_start, java.util.Date p_stop)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) n, Search sp, IN (sp.searchLevelsLocal) lp, IN (lp.nodesLocal) np, Time t WHERE sp = ?2 AND np.contactableLocal.personLocal = t.personLocal AND s = ?1 AND n.type = 'Task' AND t.taskLocal = n.taskLocal AND t.startTime >= ?3 AND t.startTime < ?4" 
 *
 * @ejb.finder signature="java.util.Collection findAllTimeForPersons(com.velocityme.interfaces.SearchLocal p_personSearch, java.util.Date p_start, java.util.Date p_stop)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Search sp, IN (sp.searchLevelsLocal) lp, IN (lp.nodesLocal) np, Time t WHERE sp = ?1 AND np.contactableLocal.personLocal = t.personLocal AND t.startTime >= ?2 AND t.startTime < ?3" 
 *
 * @ejb.finder signature="java.util.Collection findPersonTimeByDate(com.velocityme.interfaces.PersonLocal p_person, java.util.Date p_start, java.util.Date p_stop)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Person p, IN (p.timesLocal) t WHERE p=?1 AND t.startTime >= ?2 AND t.startTime < ?3"
 *
 * @ejb.finder signature="java.util.Collection findTime(com.velocityme.interfaces.SearchLocal p_search)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) n, Time t WHERE t.taskLocal = n.taskLocal AND s = ?1"
 *
 * @ejb.finder signature="java.util.Collection findTimeByDate(com.velocityme.interfaces.SearchLocal p_search, java.util.Date p_start, java.util.Date p_stop)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) n, Time t WHERE t.taskLocal = n.taskLocal AND s = ?1 AND t.startTime >= ?2 AND t.startTime < ?3"
 *
 * @ejb.finder signature="java.util.Collection findTaskTimeBeforeDate(com.velocityme.interfaces.TaskLocal p_task, java.util.Date p_date)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Task s, IN (s.timesLocal) t WHERE s = ?1 AND t.stopTime < ?2"
 *
 * @ejb.finder signature="java.util.Collection findTaskTimeAfterDate(com.velocityme.interfaces.TaskLocal p_task, java.util.Date p_date)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Task s, IN (s.timesLocal) t WHERE s = ?1 AND t.startTime >= ?2"
 *
 * @jboss.persistence create-table="true"
 *                    remove-table="false"
 */
public abstract class TimeBean implements EntityBean {
    
    /**
    * Context set by container
    */
    private javax.ejb.EntityContext m_entityContext;

    public void setEntityContext(javax.ejb.EntityContext entityContext) {
        m_entityContext = entityContext;
    }

    public void unsetEntityContext() {
        m_entityContext = null;
    }
          
    /** @ejb.create-method */
    public com.velocityme.interfaces.TimePK ejbCreate(com.velocityme.interfaces.TaskLocal p_taskLocal,
                                                      com.velocityme.valueobjects.TimeValue p_value) throws CreateException {
        try {
            setTimeId(generateNewID());
        }
        catch(ServiceUnavailableException e) {
            throw new EJBException(e.getMessage());
        }
        // EJB 2.0 spec says return null for CMP ejbCreate methods.
        return null;
    }

    public void ejbPostCreate(com.velocityme.interfaces.TaskLocal p_taskLocal,
                              com.velocityme.valueobjects.TimeValue p_value) throws CreateException {
        // CMR relations must be set in ejbPostCreate
        setTimeValue(p_value);
        setTaskLocal(p_taskLocal);
    }

    /**
     * Retrive a unique creation id to use for this bean.  This will end up
     * demarcating this bean from others when it is stored as a record
     * in the database.
     *
     * @return Returns an integer that can be used as a unique creation id.
     *
     * @throws ServiceUnavailableException Indicating that it was not possible
     *                                     to retrieve a new unqiue ID because
     *                                     the service is not available
     **/
    private Integer generateNewID() throws ServiceUnavailableException {
        int lUniqueId = -1;
        try {            
            SequenceGenerator lBean = SequenceGeneratorUtil.getHome().create();
            lUniqueId = lBean.getNextNumber("time","timeId");
            lBean.remove();
        }
        catch ( NamingException ne ) {
            throw new ServiceUnavailableException( "Naming lookup failure: " + ne.getMessage() );
        }
        catch ( CreateException ce ) {
            throw new ServiceUnavailableException( "Failure while creating a generator session bean: " + ce.getMessage() );
        }
        catch ( RemoveException re ) {
            // When the Bean cannot be removed after a while it will be taken back by the container
            // therefore ignore this exception
        }
        catch ( RemoteException rte ) {
            throw new ServiceUnavailableException( "Remote exception occured while accessing generator session bean: " +  rte.getMessage() );
        }
        
        return new Integer(lUniqueId);
    }
    
    /**
     *  This gets a local object from a remote object.
     *  @ejb.interface-method view-type="remote"
     */
    public com.velocityme.interfaces.TimeLocal getLocal() {
        return (TimeLocal)m_entityContext.getEJBLocalObject();
    }
    
    /** @ejb.interface-method view-type="local" */
    public abstract com.velocityme.valueobjects.TimeValue getTimeValue();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTimeValue(com.velocityme.valueobjects.TimeValue p_value);
        
    //=======================================================================
    //
    //                   ATTRIBUTES
    //
    //=======================================================================
      
    /**
     * @ejb.persistence column-name="timeId"
     * @ejb.interface-method view-type="local"
     * @ejb.pk-field 
     */
    public abstract java.lang.Integer getTimeId();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTimeId(java.lang.Integer timeId);

    /**
     * @ejb.persistence column-name="description"
     *                  jdbc-type="VARCHAR"
     *                  sql-type="${velocityme.sql.text.type}"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.lang.String getDescription();
    /** @ejb.interface-method view-type="local" */
    public abstract void setDescription(java.lang.String description);
    
    /**
     * @ejb.persistence column-name="startTime"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getStartTime();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStartTime(java.util.Date startTime);

    /**
     * @ejb.persistence column-name="stopTime"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getStopTime();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStopTime(java.util.Date stopTime);

    /**
     * @ejb.persistence column-name="remainingDuration_min"
     * @ejb.interface-method view-type="both"
     */
    public abstract java.lang.Integer getRemainingDuration_min();
    /** @ejb.interface-method view-type="local" */
    public abstract void setRemainingDuration_min(java.lang.Integer remainingDuration_min);
    
    //=======================================================================
    //
    //                   RELATIONSHIPS
    //
    //=======================================================================
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Time"
     *               role-name="Time-has-a-Task"
     * @jboss.relation fk-column="taskIdFk"
     *                 related-pk-field="taskId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.TaskValue"
     *                   aggregate-name="TaskValue"
     */
    public abstract com.velocityme.interfaces.TaskLocal getTaskLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTaskLocal(com.velocityme.interfaces.TaskLocal taskLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="State-Time"
     *               role-name="Time-has-a-State"
     *               target-ejb="State"
     *               target-role-name="State-has-many-Times"
     *               target-multiple="yes"
     * @jboss.relation fk-column="stateIdFk"
     *                 related-pk-field="stateId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.StateValue"
     *                   aggregate-name="StateValue"
     */
    public abstract com.velocityme.interfaces.StateLocal getStateLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStateLocal(com.velocityme.interfaces.StateLocal stateLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Person-Time"
     *               role-name="Time-has-a-Person"
     * @jboss.relation fk-column="personIdFk"
     *                 related-pk-field="personId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.PersonValue"
     *                   aggregate-name="PersonValue"
     */
    public abstract com.velocityme.interfaces.PersonLocal getPersonLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setPersonLocal(com.velocityme.interfaces.PersonLocal personLocal);
    
    //=======================================================================
    //
    //                   MANAGEMENT METHODS
    //
    //=======================================================================
    
    /**
     *  @ejb.interface-method view-type="local"
     */
    public java.lang.Long getDuration() {
        return new Long(getStopTime().getTime() - getStartTime().getTime());
    }
    
}
